﻿using System;
using System.Collections.Generic;
using SCG.SolarVengeanceEngine;
using SCG.General;

namespace SCG.SolarVengeance.Scenarios
{
    public class RingNebula : Scenario
    {
        //don't assign capitals
        public override bool AssignCapitals
        {
            get
            {
                return false;
            }
        }

        public override bool UsesCapitals
        {
            get
            {
                return false;
            }
        }

        //Build the scenario
        public override void BuildScenario(int numPlayers, int capitalValues, int startingResources)
        {
            CreateStarCluster(2, 50, 50, 50, 50, 5, 3);
            Game.StarSystems[0].Name = "Sulafat";
            Game.StarSystems[1].Name = "Sheliak";

            //Create the nebula
            CreateTerrainImage(TerrainType.Nebula, "RingNebula", 38, 36, 0.5);

            //Determine fleet values for each player, they all share equal strengths
            int spyRange = Random(4, 6);
            int scanRange = Random(spyRange + 1, 15);
            int bs = Random(20, 40);
            int stRange = Random(5, 10);

            //Assign fleet locations of each player, make sure they are not too close to each other, and outside nebula
            List<SCGPoint> pts = new List<SCGPoint>();
            foreach (Player p in Game.Players)
            {
                SCGPoint testPoint = new SCGPoint();
                bool pointOK = false;
                do
                {
                    //get a random point about 40 spaces away from center
                    testPoint.X = Random(0, 99);
                    testPoint.Y = Random(0, 99);
                    double dist = Distance(testPoint.X, testPoint.Y, 50, 50);
                    if (dist > 35 && dist < 45)
                    {
                        pointOK = true;

                        //must also be at least 20 away from all other players
                        foreach(SCGPoint ptTest in pts)
                            if (Distance(testPoint.X, testPoint.Y, ptTest.X, ptTest.Y) < 20)
                            {
                                pointOK = false;
                                break;
                            }
                    }
                }
                while (!pointOK);

                //this is the fleet location!
                pts.Add(testPoint);

                //center their spyship at this location
                int x = (int)testPoint.X;
                int y = (int)testPoint.Y;
                CreateStarShip(x, y, p, StarShipType.SpyShip, 16, spyRange, false);

                //create scanship below it
                CreateStarShip(x, y + 1, p, StarShipType.ScanShip, 20, scanRange, false);

                //create W3 scouts
                for (int scout = 0; scout < 8; scout++)
                    CreateStarShip(x + 2, y - 4 + scout, p, StarShipType.WarShip, 14, 3, false);

                //create W4 battery
                for (int w4 = 0; w4 < 6; w4++)
                    CreateStarShip(x + 1, y - 3, p, StarShipType.WarShip, 12, 4, false);

                //create W6 batteries
                for (int w6 = 0; w6 < 2; w6++)
                {
                    CreateStarShip(x, y - 1 - w6, p, StarShipType.WarShip, 10, 6, false);
                    CreateStarShip(x, y + 1 + w6, p, StarShipType.WarShip, 10, 6, false);
                }

                //create BattleStation
                CreateStarShip(x - 1, y, p, StarShipType.BattleStation, 6, bs, false);

                //create StarTillery
                for (int st = 0; st < 2; st++)
                    CreateStarShip(x - 2, y - st, p, StarShipType.StarTillery, 14, stRange, false);

                //create cloaked groups
                for (int c = 0; c < 4; c++)
                    CreateStarShip(x - 3, y, p, StarShipType.WarShip, 12, 4, true);
            }

            //Create Pulsars just outside nebula perimiter
            int pulsars = Random(3, 6);
            while (pulsars > 0)
            {
                bool pulsarOK = false;
                SCGPoint ptPulsar = new SCGPoint();
                do
                {
                    ptPulsar = new SCGPoint(Random(0, 99), Random(0, 99));
                    double dist = Distance(ptPulsar.X, ptPulsar.Y, 50, 50);
                    pulsarOK = dist < 15 && dist > 5;
                }
                while (!pulsarOK);
                CreatePulsar((int)ptPulsar.X, (int)ptPulsar.Y);
                pulsars--;
            }

            //Create wormholes in center that lead out
            int wormholes = Random(2, 5);
            while (wormholes > 0)
            {
                CreateWormhole(Random(40, 60), Random(40, 60), Random(30, 70), Random(30, 70));
                wormholes--;
            }
        }

        //Describe the scene
        public override string Description
        {
            get
            {
                return "The Ring Nebula was the setting of one of the most crucial battles among the Star Lords.  " +
                    "The Nebula was many parsecs away from any of the Lords' territories, so they converged with large fleets, " +
                    "in an effort to conquer the 2 nearby StarSystem.  The Scenario ends when one Star Lord holds both Sulafat and " +
                    "Sheliak for 100 consecutive Impulses.";
            }
        }

        //Our custom Victory Conditions
        public override bool VictoryReached()
        {
            //Same Player must hold both Stars for 100 impulses
            if (Game.StarSystems[0].Owner == Game.StarSystems[1].Owner && Game.StarSystems[0].Owner != null)
            {
                Player owner = Game.StarSystems[0].Owner;
                if (owner == _lastOwner)
                {
                    _counter++;
                    if (_counter >= 100)
                    {
                        _lastOwner.Victor = true;
                        return true;
                    }
                }
                else
                {
                    _lastOwner = owner;
                    _counter = 0;
                }
            }
            else
                _lastOwner = null;
            return false;
        }

        //Private members
        private int _counter = 0;
        private Player _lastOwner = null;
    }
}
